import { JavascriptGenerator, javascriptGenerator } from "blockly/javascript";
import { Tanslate } from "./translate";
import * as Blockly from 'blockly/core';
import { WorkspaceSvg } from "blockly/core";
import { getValue } from "./com";

export namespace Numbers {
    const blocks = [
        {
            'key': 'math_number',
            'message0': '%1',
            'args0': [
                {
                    'type': 'field_number',
                    'name': 'NUM',
                    'value': 0,
                },
            ],
            'output': 'Number',
            'helpUrl': '%{BKY_MATH_NUMBER_HELPURL}',
            'style': 'math_blocks',
            'tooltip': '%{BKY_MATH_NUMBER_TOOLTIP}',
        },
        {
            'key': 'math_arithmetic',
            'message0': '%1 %2 %3',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'A',
                    'check': 'Number',
                },
                {
                    'type': 'field_dropdown',
                    'name': 'OP',
                    'options': [
                        ['%{BKY_MATH_ADDITION_SYMBOL}', '+'],
                        ['%{BKY_MATH_SUBTRACTION_SYMBOL}', '-'],
                        ['%{BKY_MATH_MULTIPLICATION_SYMBOL}', '*'],
                        ['%{BKY_MATH_DIVISION_SYMBOL}', '/'],
                        ['%{BKY_MATH_POWER_SYMBOL}', '**'],
                        ['%', '%'],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'B',
                    'check': 'Number',
                },
            ],
            'inputsInline': true,
            'output': 'Number',
            'style': 'math_blocks',
            'helpUrl': '%{BKY_MATH_ARITHMETIC_HELPURL}'
        },
        {
            'key': 'math_single',
            'message0': '%1 %2',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'OP',
                    'options': [
                        ['%{BKY_MATH_SINGLE_OP_ROOT}', 'ROOT'],
                        ['%{BKY_MATH_SINGLE_OP_ABSOLUTE}', 'ABS'],
                        ['-', 'NEG'],
                        ['ln', 'LN'],
                        ['log10', 'LOG10'],
                        ['e^', 'EXP'],
                        ['10^', 'POW10'],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'NUM',
                    'check': 'Number',
                },
            ],
            'output': 'Number',
            'style': 'math_blocks',
            'helpUrl': '%{BKY_MATH_SINGLE_HELPURL}'
        },
        {
            'key': 'math_trig',
            'message0': '%1 %2',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'OP',
                    'options': [
                        ['%{BKY_MATH_TRIG_SIN}', 'SIN'],
                        ['%{BKY_MATH_TRIG_COS}', 'COS'],
                        ['%{BKY_MATH_TRIG_TAN}', 'TAN'],
                        ['%{BKY_MATH_TRIG_ASIN}', 'ASIN'],
                        ['%{BKY_MATH_TRIG_ACOS}', 'ACOS'],
                        ['%{BKY_MATH_TRIG_ATAN}', 'ATAN'],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'NUM',
                    'check': 'Number',
                },
            ],
            'output': 'Number',
            'style': 'math_blocks',
            'helpUrl': '%{BKY_MATH_TRIG_HELPURL}'
        },
        {
            'key': 'math_constant',
            'message0': '%1',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'CONSTANT',
                    'options': [
                        ['\u03c0', 'PI'],
                        ['e', 'E'],
                        ['\u03c6', 'GOLDEN_RATIO'],
                        ['sqrt(2)', 'SQRT2'],
                        ['sqrt(\u00bd)', 'SQRT1_2'],
                        ['\u221e', 'INFINITY'],
                    ],
                },
            ],
            'output': 'Number',
            'style': 'math_blocks',
            'tooltip': '%{BKY_MATH_CONSTANT_TOOLTIP}',
            'helpUrl': '%{BKY_MATH_CONSTANT_HELPURL}',
        },
        {
            'key': 'math_round',
            'message0': '%1 %2',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'OP',
                    'options': [
                        ['%{BKY_MATH_ROUND_OPERATOR_ROUND}', 'ROUND'],
                        ['%{BKY_MATH_ROUND_OPERATOR_ROUNDUP}', 'ROUNDUP'],
                        ['%{BKY_MATH_ROUND_OPERATOR_ROUNDDOWN}', 'ROUNDDOWN'],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'NUM',
                    'check': 'Number',
                },
            ],
            'output': 'Number',
            'style': 'math_blocks',
            'helpUrl': '%{BKY_MATH_ROUND_HELPURL}',
            'tooltip': '%{BKY_MATH_ROUND_TOOLTIP}',
        },
        {
            'key': 'math_random_float',
            'message0': '%{BKY_MATH_RANDOM_FLOAT_TITLE_RANDOM}',
            'output': 'Number',
            'style': 'math_blocks',
            'tooltip': '%{BKY_MATH_RANDOM_FLOAT_TOOLTIP}',
            'helpUrl': '%{BKY_MATH_RANDOM_FLOAT_HELPURL}',
        },
        {
            'key': 'date_object',
            'message0': '%{date_object}',
            'output': 'Date',
            'style': 'math_blocks',
        },
        {
            'key': 'date_timestamp',
            'message0': '%{date_timestamp}',
            'output': 'Number',
            'style': 'math_blocks',
        },
        {
            'key': 'date_object_new',
            'message0': '%{from} %1 %{date_object_new}',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'VALUE',
                    'check': ['Number', 'String'],
                },
            ],
            'output': 'Date',
            'style': 'math_blocks',
        },
        {
            'key': 'date_object_get',
            'message0': '%{from} %1 %2',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'VALUE',
                    'check': 'Date',
                },
                {
                    'type': 'field_dropdown',
                    'name': 'GET',
                    'options': [
                        ['%{date_get_timestamp}', 'getTime'],
                        ['%{date_get_year}', 'getFullYear'],
                        ['%{date_get_month}', 'getMonth'],
                        ['%{date_get_date}', 'getDate'],
                        ['%{date_get_day}', 'getDay'],
                        ['%{date_get_hour}', 'getHours'],
                        ['%{date_get_minute}', 'getMinutes'],
                        ['%{date_get_second}', 'getSeconds'],
                        ['%{date_get_millisecond}', 'getMilliseconds'],
                    ],
                },
            ],
            'output': 'Number',
            'style': 'math_blocks',
        },

    ]
    export function init() {
        initGenerator()
        Tanslate.tr(blocks).forEach((item: any) => {
            Blockly.Blocks[item.key] = {
                init: function (this: Blockly.Block) {
                    this.jsonInit(item);
                    if (item.key === 'list_custom') {
                        this.setOnChange((e) => {
                            const ws = this.workspace as WorkspaceSvg;
                            if (
                                !ws.isDragging ||
                                ws.isDragging() ||
                                (e.type !== Blockly.Events.BLOCK_MOVE && e.type !== Blockly.Events.BLOCK_CREATE)
                            ) {
                                return;
                            }
                            if (needAdd(this)) {
                                //this.appendValueInput('value_' + this.getChildren(false).length);
                            }
                        })
                    }
                }
            }
        })
    }

    export function getTools() {
        const colorsBlocks = {
            kind: 'category',
            name: Blockly.Msg['numbers'],
            'colour': 230,
            contents: [] as any[]
        }
        blocks.forEach((item: any) => {
            colorsBlocks.contents.push({
                kind: 'block',
                type: item.key
            })
        })

        return colorsBlocks
    }
    const addSate = {
        last: 0
    }
    function needAdd(block: Blockly.Block) {
        const now = Date.now()
        if (addSate.last > 0 && now < addSate.last) {
            return false
        }
        const xy = block.getRelativeToSurfaceXY()
        if (xy.x < 40) {
            return false
        }
        addSate.last = now + 1000
        const ar = block.getChildren(false)
        const size = block.inputList.length
        return ar.length + 1 === size
    }

    function initGenerator() {

        javascriptGenerator.forBlock['math_arithmetic'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const A = getValue(block, generator, 'A')
            const B = getValue(block, generator, 'B')
            const OP = getValue(block, generator, 'OP')
            if (!A || !B || !OP) {
                throw new Error(block.id)
            };
            return `${A} ${OP} ${B}`;
        }

        javascriptGenerator.forBlock['math_single'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const NUM = getValue(block, generator, 'NUM')
            const OP = getValue(block, generator, 'OP')
            if (!NUM || !OP) {
                throw new Error(block.id)
            };
            if (OP === 'ROOT') {
                return `Math.sqrt(${NUM})`;
            } else if (OP === 'ABS') {
                return `Math.abs(${NUM})`;
            } else if (OP === 'NEG') {
                return `-${NUM}`;
            } else if (OP === 'LN') {
                return `Math.log(${NUM})`;
            } else if (OP === 'LOG10') {
                return `Math.log10(${NUM})`;
            } else if (OP === 'EXP') {
                return `Math.exp(${NUM})`;
            } else {
                return `Math.pow(10,${NUM})`;
            }
        }

        javascriptGenerator.forBlock['math_trig'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const NUM = getValue(block, generator, 'NUM')
            const OP = getValue(block, generator, 'OP')
            if (!NUM || !OP) {
                throw new Error(block.id)
            };
            if (OP === 'SIN') {
                return `Math.sin(${NUM})`;
            } else if (OP === 'COS') {
                return `Math.cos(${NUM})`;
            } else if (OP === 'TAN') {
                return `Math.tan(${NUM})`;
            } else if (OP === 'ASIN') {
                return `Math.asin(${NUM})`;
            } else if (OP === 'ACOS') {
                return `Math.acos(${NUM})`;
            } {
                return `Math.atan(${NUM})`;
            }
        }

        javascriptGenerator.forBlock['math_round'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const NUM = getValue(block, generator, 'NUM')
            const OP = getValue(block, generator, 'OP')
            if (!NUM || !OP) {
                throw new Error(block.id)
            };
            if (OP === 'ROUND') {
                return `Math.round(${NUM})`;
            } else if (OP === 'ROUNDUP') {
                return `Math.ceil(${NUM})`;
            } else {
                return `Math.floor(${NUM})`;
            }
        }

        javascriptGenerator.forBlock['date_object'] = function () {
            return '(new Date())';
        }

        javascriptGenerator.forBlock['date_timestamp'] = function () {
            return 'Date.now()';
        }

        javascriptGenerator.forBlock['date_object_new'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const VALUE = getValue(block, generator, 'VALUE')
            if (!VALUE) {
                throw new Error(block.id)
            };
            return `(new Date(${VALUE}))`;
        }

        javascriptGenerator.forBlock['date_object_get'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const VALUE = getValue(block, generator, 'VALUE')
            const GET = getValue(block, generator, 'GET')
            if (!VALUE) {
                throw new Error(block.id)
            };
            return `${VALUE}.${GET}()`;
        }
    }
}
